package cn.net.sinodata.system.msghandler.parse.entitymapping;

import cn.hutool.core.collection.CollectionUtil;
import org.dom4j.Element;
import org.dom4j.Node;

import java.util.List;

public class XmlEntityMapping extends BaseEntityMapping {

    @Override
    String getValueByPath(Object result, String source) {
        Element elemResult = (Element) result;
        String rootName = elemResult.getName();
        // 不存在[]直接获取
        if (!source.contains("[")) {
            String xpath = convertToXPath(rootName, source);
            Node node = elemResult.selectSingleNode(xpath);
            String value = node != null ? node.getText() : null;
            return value;
        }

        // 存在[]循环解析
        String[] sourceArr = source.split("\\.");
        Element partElement = elemResult;
        for (String partSource : sourceArr) {
            if (!partSource.contains("[")) {
                partElement = partElement.element(partSource);
                continue;
            }
            // 判断是属性、标签还是数组
            if (partSource.contains("@") && partSource.contains("=")) {
                // 获取的属性
                int i = partSource.indexOf("[");
                String name = partSource.substring(0, i);
                String attrNameValue = partSource.substring(i+2, partSource.length()-1);
                String[] attrNameValueArr = attrNameValue.split("=");
                String attrName = attrNameValueArr[0];
                String attrValue = attrNameValueArr[1];
                List<Element> elements = partElement.elements(name);
                if (CollectionUtil.isEmpty(elements)) {
                    return null;
                }
                for (Element element : elements) {
                    String value = element.attributeValue(attrName);
                    if (attrValue.equals(value)) {
                        partElement = element;
                        break;
                    }
                }
            } else if (partSource.contains("@")) { // 取第几个数组的暂未实现
                //获取的是标签
                int i = partSource.indexOf("[");
                String name = partSource.substring(0, i);
                String attrName = partSource.substring(i+2, partSource.length()-1);
                Element element = partElement.element(name);
                String attrValue = element.attributeValue(attrName);
                return attrValue;
            } else {
                // 获取的是数组，获取名称和第几个元素
                int i = partSource.indexOf("[");
                String name = partSource.substring(0, i);
                String indexStr = partSource.substring(i+1, partSource.length()-1);
                Integer index = Integer.valueOf(indexStr);
                List<Element> elements = partElement.elements(name);
                if (CollectionUtil.isEmpty(elements) || elements.size() < index) {
                    return null;
                }
                partElement = elements.get(index);
            }
        }
        if (partElement == null) {
            return null;
        }
        return partElement.getText().trim();
    }

    /**
     * 将点替换为斜杠
     * @param source
     * @return
     */
    private static String convertToXPath(String rootName, String source) {
        String xpath = source.replace('.', '/');
        xpath = "/" + rootName + "/" + xpath;
        return xpath;
    }

    /**
     * 将数据库映射模版中的自定义路径转换为XPath格式
     * 标签值会将 books.book[id=b101].name -> /books/book[@id='b101']/name
     * @param source 自定义路径
     * @return
     */
//    private String convertToXPath(String source) {
//        String xpath = source;
//        // 判断获是否包含标签属性参数
//        if (xpath.contains("[") && xpath.contains("]")) {
//            Pattern pattern = Pattern.compile("\\[(\\w+)=([^\\]]+)\\]");
//            Matcher matcher = pattern.matcher(source);
//            //[id=b101] -> [@id='b101']
//            xpath = matcher.replaceAll("[@$1='$2']");
//        }
//        xpath = xpath.replace('.', '/');
//        return xpath;
//    }

}
